﻿Imports System.ComponentModel
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports iConverter.Contracts





Namespace Extensions

    ''' <summary>
    ''' 扩展管理器
    ''' </summary>
    ''' <remarks>
    ''' 用于搜索，加载，禁用外部扩展组件的管理器
    ''' </remarks>
    Public Class ExtensionsManager
        Implements IDisposable


        ''' <summary>
        ''' 组合容器
        ''' </summary>
        ''' <remarks></remarks>
        Dim _container As CompositionContainer


        ''' <summary>
        ''' 创建新的实例
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()


            '搜索范围
            Dim catalog = New AggregateCatalog()

            '添加当前程序目录下的 “Extensions” 文件夹
            Dim path As String = IO.Path.Combine(My.Application.Info.DirectoryPath, "Extensions")

            If Not IO.Directory.Exists(path) Then IO.Directory.CreateDirectory(path)


            '添加当前程序目录 文件夹
            catalog.Catalogs.Add(New DirectoryCatalog(My.Application.Info.DirectoryPath))

            catalog.Catalogs.Add(New DirectoryCatalog(path))


            '创建容器
            _container = New CompositionContainer(catalog)

            '填充对象
            Try
                _container.ComposeParts(Me)
            Catch ex As Exception
                My.Log.WriteException(ex)
            End Try
        End Sub


        ''' <summary>
        ''' 插件提供器
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>
        ''' 由MEF自动查找并填充的外部扩展组建
        ''' </remarks>
        <ImportMany(GetType(IPluginProvider))>
        Private Property PluginProviders As List(Of Lazy(Of IPluginProvider, IPluginProviderMetadata))



        Dim _providers As List(Of PluginProvider)

        ''' <summary>
        ''' 插件提供器
        ''' </summary>
        Public ReadOnly Property Providers() As List(Of PluginProvider)
            Get
                If Me._providers Is Nothing Then
                    Me._providers = ExtensionsFactory.GetPluginProviders(Me.PluginProviders)
                End If
                Return Me._providers
            End Get
        End Property





#Region "IDisposable Support"
        Private disposedValue As Boolean ' 检测冗余的调用

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' 释放托管状态(托管对象)。

                    For Each p In Me._providers
                        p.Dispose()

                    Next

                    Me.Providers.Clear()



                    If Me._container IsNot Nothing AndAlso Me.PluginProviders IsNot Nothing Then
                        Me._container.ReleaseExports(Of IPluginProvider, IPluginProviderMetadata)(Me.PluginProviders)


                        If Me.PluginProviders Is Nothing Then
                            My.Log.WriteEntry("PluginProviders is successful released.", TraceEventType.Verbose)

                        Else
                            My.Log.WriteEntry(String.Format("PluginProviders is Not released. Have counts is: {0} .", Me.PluginProviders.Count), TraceEventType.Verbose)
                        End If
                    End If
                    Me._container.Dispose()
                End If

                Me._providers = Nothing
                Me.PluginProviders = Nothing
                Me._container = Nothing

            End If
            Me.disposedValue = True
        End Sub


        'Protected Overrides Sub Finalize()
        '    ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' Visual Basic 添加此代码是为了正确实现可处置模式。
        Public Sub Dispose() Implements IDisposable.Dispose
            ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class

End Namespace

